As those skilled in the art are familiar, software programs make use of variables, for which storage space must be allocated in memory. Often the storage space is allocated in the form of a stack.
Some programs organize their variables into levels to simplify their data structure. For example, some variables, known as local-scope variables, may be used only in one function (function-scope) or one block of statements (block-scope) in the program. Other variables, known as global-scope variables, may be used by the entire program. For example, Table 1, below, sets forth pseudocode illustrating two levels of local-scope variables: an array a[ ] being a function-scope variable, and array b[ ] being a block-scope variable.
TABLE 1An Example of Function-Scope and Block-Scope Variablesvoid foo( ) {int a[100];if (...)int b[100];...}}
For purposes of understanding Table 1 and the remainder of this disclosure, the terms “foo” and “bar” are arbitrary names of functions. Any function can therefore be substituted for “foo” or “bar.”
Some programs are parallel programs, in that they are capable of being executed in parallel in a parallel processor, such as a graphics processing unit (GPU). Parallel programs have sequential regions of code that cannot be executed in parallel and parallel regions of code that can be executed in parallel, in threads. In parallel programs, multiple threads need to gain access to some local-scope variables as defined by the programming model according to which the program was developed. OpenMP and OpenACC are two examples of conventional programming models for developing parallel programs. Tables 2 and 3, below, set forth pseudocode illustrating respective OpenMP and OpenACC examples.
TABLE 2An OpenMP Examplevoid foo( ) {int a[100];#pragma omp parallel shared(a){// a[ ] can be accessed by all threads in the OpenMP region.}}
TABLE 3An OpenACC Examplevoid foo( ) {int a[100];#pragma acc loop worker{// a[ ] can be accessed by all workers in the gang}}